package com.campus.counseling.service.impl;

import com.campus.counseling.entity.TrainingData;
import com.campus.counseling.service.EmotionDictionary;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StreamUtils;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class PsyQADataLoaderImpl {

    private final ObjectMapper objectMapper;
    private final EmotionDictionary emotionDictionary;
    
    @Value("${psyqa.data.path}")
    private String dataPath;

    public List<TrainingData> loadPsyQAData() {
        List<TrainingData> trainingDataList = new ArrayList<>();
        
        try {
            // 从 classpath 加载文件
            String resourcePath = "data/PsyQA_example.json";
            log.info("开始加载PsyQA数据，资源路径: {}", resourcePath);
            
            ClassPathResource resource = new ClassPathResource(resourcePath);
            try (InputStream inputStream = resource.getInputStream()) {
                // 使用简单的缓冲区读取
                StringBuilder textBuilder = new StringBuilder();
                try (java.io.BufferedReader reader = new java.io.BufferedReader(
                        new java.io.InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        textBuilder.append(line);
                    }
                }
                String jsonContent = textBuilder.toString();
                JsonNode rootNode = objectMapper.readTree(jsonContent);
                
                if (!rootNode.isArray()) {
                    log.error("数据格式错误：根节点不是数组");
                    throw new RuntimeException("数据格式错误：根节点不是数组");
                }
                
                log.info("开始解析数据，共 {} 条记录", rootNode.size());
                int processedCount = 0;
                int successCount = 0;
                
                for (JsonNode dataNode : rootNode) {
                    try {
                        processedCount++;
                        String question = dataNode.get("question").asText("");
                        String description = dataNode.get("description").asText("");
                        String keywords = dataNode.get("keywords").asText("");
                        
                        if (question.trim().isEmpty()) {
                            log.warn("第 {} 条数据的问题为空，跳过", processedCount);
                            continue;
                        }
                        
                        JsonNode answersNode = dataNode.get("answers");
                        if (!answersNode.isArray() || answersNode.size() == 0) {
                            log.warn("第 {} 条数据没有答案，跳过", processedCount);
                            continue;
                        }
                        
                        JsonNode firstAnswer = answersNode.get(0);
                        String answerText = firstAnswer.get("answer_text").asText("");
                        
                        if (answerText.trim().isEmpty()) {
                            log.warn("第 {} 条数据的答案为空，跳过", processedCount);
                            continue;
                        }
                        
                        List<TrainingData.LabelSequence> labelSequences = new ArrayList<>();
                        if (firstAnswer.get("has_label").asBoolean()) {
                            JsonNode labelsNode = firstAnswer.get("labels_sequence");
                            for (JsonNode labelNode : labelsNode) {
                                labelSequences.add(TrainingData.LabelSequence.builder()
                                    .start(labelNode.get("start").asInt())
                                    .end(labelNode.get("end").asInt())
                                    .type(labelNode.get("type").asText())
                                    .build());
                            }
                        }
                        
                        // 使用EmotionDictionary进行情感分析
                        String combinedText = question + " " + description + " " + answerText;
                        double emotionScore = emotionDictionary.calculateEmotionScore(combinedText);
                        String emotionType = emotionDictionary.determineEmotionType(combinedText);
                        
                        trainingDataList.add(TrainingData.builder()
                            .question(question)
                            .description(description)
                            .keywords(keywords)
                            .answer(answerText)
                            .labelSequences(labelSequences)
                            .emotionScore(emotionScore)
                            .emotionType(emotionType)
                            .build());
                        
                        successCount++;
                        
                        if (processedCount % 100 == 0) {
                            log.info("已处理 {} 条数据，成功 {} 条", processedCount, successCount);
                        }
                        
                    } catch (Exception e) {
                        log.error("处理第 {} 条数据时出错: {}", processedCount, e.getMessage());
                    }
                }
                
                log.info("数据加载完成，共处理 {} 条数据，成功 {} 条", processedCount, successCount);
            }
            
        } catch (Exception e) {
            log.error("加载PsyQA数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("加载PsyQA数据失败", e);
        }
        
        if (trainingDataList.isEmpty()) {
            log.error("没有加载到有效的训练数据");
            throw new RuntimeException("没有加载到有效的训练数据");
        }
        
        return trainingDataList;
    }
} 